package com.xinsmartsky.penmaji.SerialPort;

import android.os.Environment;
import android.util.Log;
import android.widget.Toast;

import com.xinsmartsky.penmaji.model.MemRegionModel;

import org.apache.http.util.EncodingUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * Created by wangxiao on 16-1-27.
 */
public class FileOperation {

    private MemRegionModel mem = new MemRegionModel();
    private int new_crc_add = 0;//重新计算的校验和

    //判断SdCard是否存在（当没有Sd,内置ROM被识别）
    public boolean isSdCsrdExist() {
        return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
    }

    //获取文件的存储路径
    public String getFilePath() {
        boolean exist = isSdCsrdExist();
        String filepath = "";
        if (exist) {
            //getAbsolutePath():取得绝对路径 SD卡根目录路径下新建的文件夹InkPrinter
           filepath = Environment.getExternalStorageDirectory().getAbsolutePath()+ "/" + "InkPrinter";
            //新建文件夹
            File path1 = new File(filepath);
            if (!path1.exists()) {
                path1.mkdirs();
            }
        } else {
            Log.i("fd", "filepath 不适用");
        }
        return filepath;
    }

    //在Sd卡上创建文件
    public boolean CreateFile(String filename) throws IOException {
        File file = new File(getFilePath() + "//" + filename);
        if (!file.exists()) {
            return file.createNewFile();
        }else {
            return false;
        }
    }

//获取文件夹中的所有文件的文件名
    public String[] getAllFilenames(){
        File dir = new File(getFilePath());
        String filenames[];
        filenames = dir.list();
        return filenames;
    }

    //使用FileputStream读取文件内容
    public byte[] ReadDataFromFile(String filename) {
        byte[] bt = new byte[]{};
        try {
            File file = new File(getFilePath() + "/" + filename);
            FileInputStream fin = new FileInputStream(file);
            bt = new byte[fin.available()];
            fin.read(bt);
            fin.close();
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        Log.i("ccc", "3==============" + bt.length + "路径==" + getFilePath() + "/" + filename);
        return bt;
    }

    //将文件中的数据打印出来
    public void PrintData() {
        byte[] info = new byte[]{};
        info = ReadDataFromFile("serialdatablock.txt");
        int address = 0x400;
        String data = "";
        Log.i("fd", "数据块编号（H）：" + Integer.toHexString(info[0] & 0x000000ff));
        for (int index = 1; index < (info.length - 1); index++) {
            data += (Integer.toHexString(info[index] & 0x000000ff) + " ");
            if (index % 16 == 0) {
                //打印
                Log.i("fd", Integer.toHexString(address) + " : " + data +"(" + index + ")");
                data = "";
                address += 16;
                if(address == 0xd00){
                    address = 0x1000;
                    Log.i("fd", "data block2------------------------------------------------");
                }
                else if(address == 0x1a00){
                    Log.i("fd", "data block3------------------------------------------------");
                }
            }
        }
        Log.i("fd", "校验和是 : " + (Integer.toHexString(info[info.length - 1] & 0x000000ff) + " "));
    }

    //写入数据
    public synchronized boolean WriteDataToFile(byte[] info, String name) {
        boolean wdt = false;
            try {

                File file = new File(getFilePath() + "/" + name);
                FileOutputStream fout = new FileOutputStream(file);
                fout.write(info);
                fout.close();
                wdt = true;
                Log.i("ccc", "2==============" + info.length + "路径==" + getFilePath() + "/" + name);
            } catch (Exception e) {
                Log.i("ccc", " write error!");
                Log.i("fd", "写文件异常");
                e.printStackTrace();
                wdt = false;
            }
        return wdt;
    }

    //设置数值 同一时间只能有一个线程修改文件内容 加synchronized
    public synchronized void SetDataToAddress(int address, byte setdata) {
        Log.i("fd", "开始设置....");
        byte[] setbytearray = new byte[]{};
        setbytearray = ReadDataFromFile("serialdatablock.txt");
        if (setbytearray.length > 0) {
            int posi = (address - 0x400 + 1);
            if (address > 0x1000) {
                posi = (address - 0x400 + 1 - (0x1000 - 0xd00));
            }
            setbytearray[posi] = setdata;
            //重新计算校验和
            for (int index = 0; index < (setbytearray.length - 1); index++) {
                new_crc_add += setbytearray[index];
            }
            setbytearray[setbytearray.length - 1] = (byte) new_crc_add;
            new_crc_add = 0;
            //写到文件中
            WriteDataToFile(setbytearray, "serialdatablock.txt");
//            Log.i("fd", "新的和是:" + Integer.toHexString(setbytearray[setbytearray.length - 1] & 0x000000ff));
        }
        Log.i("fd", "设置完成....");
    }


    //设置数据块的多个数值
    public synchronized void setDataBlockValues(int[] address, byte[] setdata) {
        byte[] setbytearray = new byte[]{};
        setbytearray = ReadDataFromFile("serialdatablock.txt");
        if (setbytearray.length > 0) {
            for(int len = 0; len < address.length; len++){
                int posi = (address[len] - 0x400 + 1);
                if (address[len] > 0x1000) {
                    posi = (address[len] - 0x400 + 1 - (0x1000 - 0xd00));
                }
                setbytearray[posi] = setdata[len];
            }
            //重新计算校验和
            for (int index = 0; index < (setbytearray.length - 1); index++) {
                new_crc_add += setbytearray[index];
            }
            setbytearray[setbytearray.length - 1] = (byte) new_crc_add;
            new_crc_add = 0;
            WriteDataToFile(setbytearray, "serialdatablock.txt");
        }else{
            Log.i("fd", "读取文件内容失败");
        }
    }

    //设置
    private int zitiaonum = 0;//字条号
    private int practicelen = 0;//字的实际长度
    /*写入数组(编辑汉字和图形时)
    *zitiaonum:字条号;  ArrayLong:汉字数组; practicelen:字条实际长度(字的个数)*/
    public synchronized void SetArrayToAddress(int type, int num, byte[] ArrayLong, int lenth) {
        zitiaonum = num;
        practicelen = lenth;
        switch (type) {
            //字条 16*16
            case 1: {
                SetFile(ArrayLong, mem.Chinese_16, 3328);
                break;
            }
            //图标24*24
            case 2: {
                SetFile(ArrayLong, mem.drawing_24, 512);
                break;
            }
            //图标32*32
            case 3: {
                SetFile(ArrayLong, mem.drawing_32, 512);
                break;
            }
            //数字和字母
            case 4:{
//                SetFile(ArrayLong, , 512);
                break;
            }
        }
    }

    /*将数组写入到文件中[绘图]
    *sindex:类型块的起始下标
     * diff: 字条(图标)1和字条(图标)2的差值*/
    private void SetFile(byte[] ArrayLong, int sindex, int diff) {
        byte[] setarray = new byte[]{};
        setarray = ReadDataFromFile("serialdatablock.txt");
        //起始下标
        int startindex = sindex + diff * (zitiaonum - 1) - 1;//打印出的下标
        if (setarray.length > 12369) {//=============>总字节数-1
            if(practicelen < 0){
                //数字和字母
            }else{
                //其它
                for (int i = 0; i < ArrayLong.length; i++) {
                    setarray[startindex + 1 + i] =  ArrayLong[i];
                }
                setarray[startindex] = (byte) practicelen;//每块第一个字节存放长度
            }
            //校验和
            for (int index = 0; index < (setarray.length - 1); index++) {
                new_crc_add += setarray[index];
            }
            setarray[setarray.length - 1] = (byte) new_crc_add;
            new_crc_add = 0;
            WriteDataToFile(setarray, "serialdatablock.txt");
        }

    }

}
